package com.simulation.web.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.simulation.web.domain.TechCollection;
import com.simulation.web.domain.TechPost;
import com.simulation.web.domain.TechTaskSubmissions;
import com.simulation.web.dto.TaskSubmissionsDTO;
import com.simulation.web.entity.OssFile;
import com.simulation.web.mapper.*;
import com.simulation.web.service.TaskSubmissionsService;
import com.simulation.web.utils.PostStatusEnum;
import com.simulation.web.utils.RelatedTypeEnum;
import com.simulation.web.utils.TaskEnum;
import com.simulation.web.vo.*;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @Author 唐雄杰
 * @Date 2024-08-26 19:20
 **/
@Service
@AllArgsConstructor
public class TaskSubmissionsServiceImpl implements TaskSubmissionsService {
    private final TaskSubmissionsMapper taskSubmissionsMapper;

    private final PostMapper postMapper;

    private final CollectionMapper collectionMapper;

    private final MinioTemplate minioTemplate;

    private final TeamMapper teamMapper;

    private final TaskMapper taskMapper;


    @Override
    public void batchInsert(List<TechTaskSubmissions> taskSubmissionsList, String bucketName) {
        taskSubmissionsList.stream().forEach(taskSubmissions -> {
            if (taskSubmissions.getRelatedType().equals(RelatedTypeEnum.POST.name().toLowerCase())) {
                // 查询源项目信息
                TechPostVO techPostVO = postMapper.getById(taskSubmissions.getRelatedId());
                // 给新成员分配任务
                taskSubmissions.setStatus(TaskEnum.PROCESSING.name().toLowerCase());
                // 复制项目资源
                String code = copyCode(bucketName, techPostVO.getCode());
                // 复制项目信息
                Long relatedId = copyPost(techPostVO, taskSubmissions.getUserId(), code);
                taskSubmissions.setRelatedId(relatedId);
            } else {
                // 查询源合集信息
                TechCollectionVO techCollectionVO = collectionMapper.getById(taskSubmissions.getRelatedId());

                List<TechPostVO> techPostList = postMapper.getPostByCollectionId(taskSubmissions.getRelatedId());
                if (CollectionUtil.isEmpty(techPostList)) {
                    return;
                }
                // 复制合集
                Long relatedId = copyCollection(techCollectionVO, taskSubmissions.getUserId());
                // 把项目复制给团队成员
                techPostList.stream().forEach(techPost -> {
                    // 复制项目资源
                    String code = copyCode(bucketName, techPost.getCode());
                    // 复制项目
                    techPost.setCollectionId(relatedId);
                    copyPost(techPost, taskSubmissions.getUserId(), code);
                });
                // 给团队成员分配任务
                taskSubmissions.setStatus(TaskEnum.PROCESSING.name().toLowerCase());
                taskSubmissions.setRelatedId(relatedId);
            }
            taskSubmissions.setStatus(TaskEnum.PROCESSING.name().toLowerCase());
            TechTaskVO techTaskVO = taskMapper.getTaskDetailById(taskSubmissions.getTaskId());
            if (techTaskVO != null) {
                taskSubmissions.setDeadline(techTaskVO.getDeadline());
            }
        });
        taskSubmissionsMapper.batchInsert(taskSubmissionsList);
    }

    @Override
    public PageInfo<TechTaskSubmissionsVO> getPageByTaskId(TaskSubmissionsDTO taskSubmissionsDTO) {
        PageHelper.startPage(taskSubmissionsDTO.getPageNum(), taskSubmissionsDTO.getPageSize());
        List<TechTaskSubmissionsVO> taskSubmissionsList = taskSubmissionsMapper.getPageByTaskId(taskSubmissionsDTO);
        return new PageInfo<>(taskSubmissionsList);
    }

    @Override
    public TechTaskSubmissionsVO getById(Long id) {
        TechTaskSubmissionsVO techTaskSubmissionsVO = taskSubmissionsMapper.getById(id);
        getRelatedName(techTaskSubmissionsVO);
        List<TechPostVO> techPostVOList = new ArrayList<>();
        if (techTaskSubmissionsVO.getRelatedType().equals(RelatedTypeEnum.POST.name().toLowerCase())) {
            TechPostVO techPostVO = postMapper.getById(techTaskSubmissionsVO.getRelatedId());
            techPostVOList.add(techPostVO);
        } else if(techTaskSubmissionsVO.getRelatedType().equals(RelatedTypeEnum.COLLECTION.name().toLowerCase())){
            List<TechPostVO> costVOList = postMapper.getPostByCollectionId(techTaskSubmissionsVO.getRelatedId());
            techPostVOList.addAll(costVOList);
        }
        techTaskSubmissionsVO.setTechPostVOList(techPostVOList);
        return techTaskSubmissionsVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Long id) {
        TechTaskSubmissionsVO techTaskSubmissionsVO = taskSubmissionsMapper.getById(id);
        // 删除对应的合集或项目
        if (techTaskSubmissionsVO.getRelatedType().equals(RelatedTypeEnum.POST.name().toLowerCase())) {
            TechPostVO techPostVO = postMapper.getById(techTaskSubmissionsVO.getRelatedId());
            minioTemplate.removeFile(techPostVO.getCode());
            // 删除项目
            postMapper.delete(techPostVO.getId());
        } else {
            TechCollectionVO techCollectionVO = collectionMapper.getById(techTaskSubmissionsVO.getRelatedId());
            // 删除合集
            collectionMapper.delete(techCollectionVO.getId());
            List<TechPostVO> techPostVOList = postMapper.getPostByCollectionId(techCollectionVO.getId());
            techPostVOList.stream().forEach(techPostVO -> {
                minioTemplate.removeFile(techPostVO.getCode());
                // 删除项目
                postMapper.delete(techPostVO.getId());
            });
        }

        List<Long> idList = new ArrayList<>();
        idList.add(id);
        taskSubmissionsMapper.deleteById(idList);
    }

    @Override
    public void updateIgnoreNull(TechTaskSubmissions techTaskSubmission) {
        taskSubmissionsMapper.updateIgnoreNull(techTaskSubmission);
        // 更细
    }

    @Override
    public PageInfo<TechTaskSubmissionsVO> getPageByUserId(TaskSubmissionsDTO taskSubmissionsDTO) {
        PageHelper.startPage(taskSubmissionsDTO.getPageNum(), taskSubmissionsDTO.getPageSize());
        List<TechTaskSubmissionsVO> techTaskSubmissionsVOList = taskSubmissionsMapper.getPageByUserId(taskSubmissionsDTO.getUserId(), taskSubmissionsDTO.getStatusList());
        techTaskSubmissionsVOList.stream().forEach(techTaskSubmissionsVO -> {
            getRelatedName(techTaskSubmissionsVO);
        });
        return new PageInfo<>(techTaskSubmissionsVOList);
    }

    private void getRelatedName(TechTaskSubmissionsVO techTaskSubmissionsVO) {
        if (techTaskSubmissionsVO.getRelatedType().equals(RelatedTypeEnum.POST.name().toLowerCase())) {
            TechPostVO techPostVO = postMapper.getById(techTaskSubmissionsVO.getRelatedId());
            if (techPostVO != null && Objects.nonNull(techPostVO.getId())) {
                techTaskSubmissionsVO.setRelatedName(techPostVO.getTitle());
            }
        } else {
            TechCollectionVO techCollectionVO = collectionMapper.getById(techTaskSubmissionsVO.getRelatedId());
            if (techCollectionVO != null && Objects.nonNull(techCollectionVO.getId())) {
                techTaskSubmissionsVO.setRelatedName(techCollectionVO.getTitle());
            }
        }
        TechTeamVO techTeamVO = teamMapper.getTeamById(techTaskSubmissionsVO.getTeamId());
        if (techTeamVO != null) {
            techTaskSubmissionsVO.setTeamName(techTeamVO.getTeamName());
        }
    }

    private Long copyPost(TechPostVO oldPost, Long userId, String code) {
        TechPost techPost = new TechPost();
        BeanUtil.copyProperties(oldPost, techPost);
        techPost.setCode(code);
        techPost.setUserId(userId);
        techPost.setStatus(PostStatusEnum.TASK.name().toLowerCase());
        techPost.setViewCount(0);
        techPost.setFavoriteCount(0);
        techPost.setCommentCount(0);
        techPost.setFollowCount(0);
        techPost.setPublishTime(new Date());
        techPost.setPublishTime(new Date());
        postMapper.insert(techPost);
        return techPost.getId();
    }

    private Long copyCollection(TechCollectionVO oldCollection, Long userId) {
        TechCollection techCollection = new TechCollection();
        BeanUtil.copyProperties(oldCollection, techCollection);
        techCollection.setUserId(userId);
        techCollection.setStatus(PostStatusEnum.TASK.name().toLowerCase());
        techCollection.setViewCount(0);
        techCollection.setFavoriteCount(0);
        techCollection.setCommentCount(0);
        techCollection.setFollowCount(0);
        techCollection.setPublishTime(new Date());
        techCollection.setPublishTime(new Date());
        collectionMapper.insert(techCollection);
        return techCollection.getId();
    }

    private String copyCode(String bucketName, String code) {
        InputStream in = minioTemplate.getObject(bucketName, code);
        OssFile ossFile = minioTemplate.upLoadFile("template", "projectTemplate", MinioTemplate.getFileExtension(code), in);
        return ossFile.getName();
    }
}
